package com.lykj.lib_base.internal.utils

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.provider.Settings
import android.util.Log
import androidx.core.content.FileProvider
import com.lykj.lib_base.base.BaseActivity
import java.io.File
import java.io.FileNotFoundException


object PackageUtils {
    /**
     * 检查apk是否安装
     * @param context
     * @param packageName
     * @return
     */
    fun checkApk(context: Context, packageName: String): Boolean {
        if (null == packageName || "" == packageName)
            return false
        return try {
            context.packageManager.getApplicationInfo(
                packageName,
                PackageManager.GET_UNINSTALLED_PACKAGES
            )
            true
        } catch (e: PackageManager.NameNotFoundException) {
            false
        }
    }

    /**
     * 获取版本号
     */
    fun getVersionCode(context: Context): Int {
        val manager = context.packageManager
        var code = 0
        try {
            val info = manager.getPackageInfo(context.packageName, 0)
            code = info.versionCode
        } catch (e: PackageManager.NameNotFoundException) {
            e.printStackTrace()
        }
        return code
    }

    /**
     * 获取版本名
     */
    fun getVersionName(context: Context): String {
        val manager = context.packageManager
        var name = ""
        try {
            val info = manager.getPackageInfo(context.packageName, 0)
            name = info.versionName
        } catch (e: PackageManager.NameNotFoundException) {
            e.printStackTrace()
        }
        return name
    }

    fun installApk(activity: Activity, filePath: String?) {
        if (filePath == null) throw NullPointerException("fillPath is null!")

        val file = File(filePath)
        if (!file.exists()) {
            ToastUtils.showShort(activity, "安装包不存在")
//            throw FileNotFoundException("$filePath is not exist! or check permission")
        }
        val packPageName = activity.packageName
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            if (canRequestPackageInstalls(activity)) {
                install24(activity, file, packPageName)
            } else {
                showSettingPackageInstall(activity)
            }
        } else {
            installBelow24(activity, file)
        }
    }

    fun showSettingPackageInstall(activity: Activity) { // todo to test with android 26
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            Log.d("SettingPackageInstall", ">= Build.VERSION_CODES.O")
            val intent = Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES)
            intent.data = Uri.parse("package:${activity.packageName}")
            activity.startActivityForResult(intent, 0)
        } else {
            throw RuntimeException("VERSION.SDK_INT < O")
        }
    }

    fun canRequestPackageInstalls(activity: Activity): Boolean {
        return Build.VERSION.SDK_INT <= Build.VERSION_CODES.O || activity.packageManager.canRequestPackageInstalls()
    }

    private fun installBelow24(context: Context, file: File?) {
        val intent = Intent(Intent.ACTION_VIEW)
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        val uri = Uri.fromFile(file)
        intent.setDataAndType(uri, "application/vnd.android.package-archive")
        context.startActivity(intent)
    }

    /**
     * android24及以上安装需要通过 ContentProvider 获取文件Uri，
     * 需在应用中的AndroidManifest.xml 文件添加 provider 标签，
     * 并新增文件路径配置文件 res/xml/provider_path.xml
     * 在android 6.0 以上如果没有动态申请文件读写权限，会导致文件读取失败，你将会收到一个异常。
     * 插件中不封装申请权限逻辑，是为了使模块功能单一，调用者可以引入独立的权限申请插件
     */
    private fun install24(activity: Activity, file: File?, appId: String?) {
        if (activity == null) throw NullPointerException("context is null!")
        if (file == null) throw NullPointerException("file is null!")
        if (appId == null) throw NullPointerException("appId is null!")
        val intent = Intent(Intent.ACTION_VIEW)
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
        val packageName = activity.packageName
        val uri: Uri =
            FileProvider.getUriForFile(
                activity,
                "$packageName.fileProvider",
                file
            )
        intent.setDataAndType(uri, "application/vnd.android.package-archive")
        activity.startActivity(intent)
    }
}